package com.gpj.learn.rabbitmq.common;

import org.apache.commons.lang3.StringUtils;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;

import static java.time.temporal.ChronoField.*;

/**
 * @className DateTimeUtil
 * @description TODO
 * @author GPJ
 * @date 2021/3/8 17:54
 * @version 1.0
 **/
public class DateTimeUtil {
    public static final DateTimeFormatter TIME_FORMATTER;
    static {
        TIME_FORMATTER = new DateTimeFormatterBuilder()
                .appendValue(HOUR_OF_DAY, 2)
                .appendLiteral(':')
                .appendValue(MINUTE_OF_HOUR, 2)
                .optionalStart()
                .appendLiteral(':')
                .appendValue(SECOND_OF_MINUTE, 2)
                .toFormatter();
    }

    public static final DateTimeFormatter DATE_TIME_FORMATTER;
    static {
        // 2011-12-03 12:12:12
        DATE_TIME_FORMATTER = new DateTimeFormatterBuilder()
                .parseCaseInsensitive()
                .append(DateTimeFormatter.ISO_LOCAL_DATE)
                .appendLiteral(' ')
                .append(TIME_FORMATTER)
                .toFormatter();
    }

    public static final String DATE_TIME_STR_FORMATTER = "yyyy-MM-dd HH:mm:ss";
    public static final String TIME_STR_FORMATTER = "HH:mm:ss";

    /**
     * 获取当前时间的字符串，格式 yyyy-MM-dd HH:mm:ss
     */
    public static String now() {
        return LocalDateTime.now().format(DATE_TIME_FORMATTER);
    }

    /**
     * 获取当前时间的LocalDateTime
     */
    public static LocalDateTime nowDateTime() {
        return LocalDateTime.now().withNano(0);
    }

    /**
     * 获取当前时间的时间戳，精确到秒
     */
    public static long nowSecond() {
        return LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));
    }

    /**
     * 获取当前时间的时间戳，精确到毫秒
     */
    public static long nowMillis() {
        return System.currentTimeMillis();
    }

    /**
     * LocalDateTime转时间戳，精确到秒
     * @param dateTime LocalDateTime
     */
    public static long toSecond(LocalDateTime dateTime) {
        return dateTime.toEpochSecond(ZoneOffset.of("+8"));
    }

    /**
     * LocalDateTime转时间戳，精确到毫秒
     * @param dateTime LocalDateTime
     */
    public static long toMillis(LocalDateTime dateTime) {
        return dateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
    }

    /**
     * LocalDateTime转字符串，格式 yyyy-MM-dd
     */
    public static String formatDate(LocalDateTime dateTime) {
        return format(dateTime, "yyyy-MM-dd");
    }

    /**
     * LocalDateTime转字符串，格式 yyyy-MM-dd HH:mm:ss
     */
    public static String format(LocalDateTime dateTime) {
        return format(dateTime, DATE_TIME_FORMATTER);
    }

    /**
     * LocalDateTime转字符串，格式 自定义格式
     */
    public static String format(LocalDateTime dateTime, String format) {
        return format(dateTime, DateTimeFormatter.ofPattern(format));
    }

    /**
     * LocalDateTime转字符串，格式 自定义格式
     */
    private static String format(LocalDateTime dateTime, DateTimeFormatter format) {
        if (dateTime == null || format == null) return null;
        return dateTime.format(format);
    }

    /**
     * 时间戳转LocalDateTime
     * @param timestamp 时间戳，精确到毫秒
     */
    public static LocalDateTime timestamp2LocalDateTime(Long timestamp) {
        if (timestamp == null) return null;
        return Instant.ofEpochMilli(timestamp).atZone(ZoneOffset.ofHours(8)).toLocalDateTime();
    }

    /**
     * 字符串转LocalDateTime
     * @param dateTimeFormat 字符串，格式 yyyy-MM-dd HH:mm:ss
     */
    public static LocalDateTime dateTimeFormat2LocalDateTime(String dateTimeFormat) {
        if (StringUtils.isBlank(dateTimeFormat)) return null;
        DateTimeFormatter pattern = DateTimeFormatter.ofPattern(DATE_TIME_STR_FORMATTER);
        return LocalDateTime.parse(dateTimeFormat, pattern);
    }

    /**
     * 字符串转LocalDateTime
     * @param dateTimeFormat 字符串，格式 yyyy-MM-dd
     */
    public static LocalDateTime dateFormat2LocalDateTime(String dateTimeFormat) {
        if (StringUtils.isBlank(dateTimeFormat)) return null;
        DateTimeFormatter pattern = DateTimeFormatter.ofPattern(DATE_TIME_STR_FORMATTER);
        return LocalDateTime.parse(dateTimeFormat + " 00:00:00", pattern);
    }

    /**
     * 时间数字转字符串，用于视频时长的处理
     * @param time 时间，精确到秒
     */
    public static String secondFormat(long time) {
        if (time > 24 * 60 * 60) {
            return (time / (24 * 60 * 60)) + " day";
        } else {
            return LocalTime.ofSecondOfDay(time).format(DateTimeFormatter.ISO_LOCAL_TIME);
        }
    }

    /**
     * 毫秒时间戳转字符串
     * @param timestamp 时间，精确到毫秒
     */
    public static String millisFormat(long timestamp) {
        return format(Instant.ofEpochMilli(timestamp).atZone(ZoneOffset.ofHours(8)).toLocalDateTime());
    }

    /**
     * 字符串转秒，用于视频时长的处理
     * @param time 时间，字符串
     */
    public static int str2second(String time) {
        if (StringUtils.isNotBlank(time)) {
            try {
                if (time.indexOf("day") != -1) {
                    time = time.substring(0, time.length() - 3);
                    return Integer.parseInt(time) * 24 * 60 * 60;
                } else {
                    DateTimeFormatter pattern = DateTimeFormatter.ofPattern(TIME_STR_FORMATTER);
                    return LocalTime.parse(time, pattern).toSecondOfDay();
                }
            } catch (Exception e) {

            }
        }
        return 0;
    }

    /*public static LocalDate dateFromNow(int year, int month, int day){
        LocalDate date = LocalDate.now();
        if(year != 0){
            date = date.plusYears(year);
        }

        if(month != 0){
            date = date.plusMonths(month);
        }

        if(day != 0){
            date = date.plusDays(day);
        }

        return date;
    }

    public static LocalTime timeFromNow(int hour, int minute, int second){
        LocalTime time = LocalTime.now();
        if(hour != 0){
            time = time.plusHours(hour);
        }

        if(minute != 0){
            time = time.plusMinutes(minute);
        }

        if(second != 0){
            time = time.plusSeconds(second);
        }

        return time;
    }

    public static LocalDateTime dateTimeFromNow(int year, int month, int day, int hour, int minute, int second){
        LocalDate date = dateFromNow(year, month, day);
        LocalTime time = timeFromNow(hour, minute, second);
        return LocalDateTime.of(date, time);
    }*/
}
